﻿#define DLL_EXPORTS
#include "DP100.h"
#include <string>
#include <iostream>
#include <msclr/marshal_cppstd.h>
#include <msclr/marshal.h>
#include <vcclr.h>
#using "../Sources/ATK-DP100DLL.dll"

using namespace ATK_DP100DLL;
using namespace System;
using namespace msclr::interop;

BasicInfoIndication_t* BasicInfoIndication_p = NULL;

static void ReceBasicInfo(unsigned short v, unsigned short i)
{
    if(NULL != BasicInfoIndication_p)
    {
        return BasicInfoIndication_p(v, i);
    }
}

class gATKDP100API_t
{   
    public :
        System::Runtime::InteropServices::GCHandle handle;
        gATKDP100API_t()
        {
            auto obj = gcnew ATKDP100API();
            obj->SetReceBasicInfoEvent(gcnew ATKDP100API::ReceBasicInfo(ReceBasicInfo));
            handle = System::Runtime::InteropServices::GCHandle::Alloc(obj);
            // auto clb_obj = gcnew ATKDP100API::ReceBasicInfo(ReceBasicInfo);
            // clb_handle = System::Runtime::InteropServices::GCHandle::Alloc(clb_obj);
            // obj->SetReceBasicInfoEvent(clb_obj);
        }

        ~gATKDP100API_t()
        {
            handle.Free();
        }

    private:
        // System::Runtime::InteropServices::GCHandle clb_handle;

        
};

gATKDP100API_t gATKDP100API;

bool ConnState()
{
    return ((ATKDP100API^)(gATKDP100API.handle.Target))->ConnState;
}

bool CloseOut(uint8_t index, uint16_t iset, uint16_t vset)
{
    return ((ATKDP100API^)(gATKDP100API.handle.Target))->CloseOut(index, iset, vset);
}

bool DevOpenOrClose()
{
    return ((ATKDP100API^)(gATKDP100API.handle.Target))->DevOpenOrClose();
}


bool GetBasicInfo()
{
    return ((ATKDP100API^)(gATKDP100API.handle.Target))->GetBasicInfo();    
}

bool GetCurrentBasic(uint8_t* index, uint8_t* state, uint16_t* vset, uint16_t* iset, uint16_t* ovp, uint16_t* ocp)
{
    return ((ATKDP100API^)(gATKDP100API.handle.Target))->GetCurrentBasic(*index, *state, *vset, *iset, *ovp, *ocp);
}

bool GetDevInfo(char* devType, char* hdwVer, char* appVer, char* devSN, char* devState)
{
    System::String^ devtype;
    System::String^ hdwver;
    System::String^ appver;
    System::String^ devsn;
    System::String^ devstate;
    if (((ATKDP100API^)(gATKDP100API.handle.Target))->GetDevInfo(devtype, hdwver, appver, devsn, devstate))
    {
        marshal_as<std::string>(devtype).copy(devType, marshal_as<std::string>(devtype).length(), 0);
        marshal_as<std::string>(hdwver).copy(hdwVer, marshal_as<std::string>(hdwver).length(), 0);
        marshal_as<std::string>(appver).copy(appVer, marshal_as<std::string>(appver).length(), 0);
        marshal_as<std::string>(devsn).copy(devSN, marshal_as<std::string>(devsn).length(), 0);
        marshal_as<std::string>(devstate).copy(devState, marshal_as<std::string>(devstate).length(), 0);
        return true;
    }
    else
    {
        return false;
    }
}

bool GetGroupInfo(uint8_t index, uint16_t* iset, uint16_t* vset, uint16_t* ocp, uint16_t* ovp)
{
    return ((ATKDP100API^)(gATKDP100API.handle.Target))->GetGroupInfo(index, *iset, *vset, *ocp, *ovp);
}

bool GetSysPar(uint8_t* blklev, uint8_t* vollev, uint16_t* opp, uint16_t* otp, uint8_t* en_rep, uint8_t* en_auto_out)
{
    return ((ATKDP100API^)(gATKDP100API.handle.Target))->GetSysPar(*blklev, *vollev, *opp, *otp, *en_rep, *en_auto_out);
}

bool OpenOut(uint8_t index, uint16_t iset, uint16_t vset)
{
    return ((ATKDP100API^)(gATKDP100API.handle.Target))->OpenOut(index, iset, vset);
}

bool SetBasicInfo(uint8_t index, uint16_t iset, uint16_t vset, uint16_t ocp, uint16_t ovp)
{
    return ((ATKDP100API^)(gATKDP100API.handle.Target))->SetBasicInfo(index, iset, vset, ocp, ovp);
}

bool SetGroupInfo(uint8_t index, uint16_t iset, uint16_t vset, uint16_t ocp, uint16_t ovp)
{
    return ((ATKDP100API^)(gATKDP100API.handle.Target))->SetGroupInfo(index, iset, vset, ocp, ovp);
}

bool SetSysPar(char* appver, uint8_t blklev, uint8_t vollev, uint16_t opp, uint16_t otp, uint8_t en_rep, uint8_t en_auto_out)
{
    System::String^ appver_temp = gcnew System::String(std::string(appver).c_str());

    if (((ATKDP100API^)(gATKDP100API.handle.Target))->SetSysPar(appver_temp, blklev, vollev, opp, otp, en_rep, en_auto_out))
    {
        marshal_as<std::string>(appver_temp).copy(appver, marshal_as<std::string>(appver_temp).length(), 0);
        return true;
    }
    else
    {
        return false;
    }
}


bool UseGroup(uint8_t index)
{
    return ((ATKDP100API^)(gATKDP100API.handle.Target))->UseGroup(index, 0, 0, 0, 0);
}
